home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 40 / Amiga Format CD40 (1999-05-11)(Future Publishing)(GB)(Track 1 of 3)[!][issue 1999-06].iso / -in_the_mag- / recent_reviews / drivelight / requeststring.c < prev    next >
C/C++ Source or Header  |  1999-03-31  |  10KB  |  355 lines

  1. /*
  2.  * RequestString
  3.  *
  4.  * A program which requests a string from the user and prints it on
  5.  * the standard output.
  6.  *
  7.  * Written by Peter Bengtsson who does not agree to be held responsible
  8.  * for any damage or loss resulting from the use of this program.
  9.  *
  10.  * Use it as you wish for any and all nice things you can think of.
  11.  */
  12.  
  13. #include <proto/exec.h>
  14. #include <exec/memory.h>
  15. #include <clib/dos_protos.h>
  16. #include <pragmas/dos_pragmas.h>
  17. #include <clib/intuition_protos.h>
  18. #include <pragmas/intuition_pragmas.h>
  19. #include <clib/graphics_protos.h>
  20. #include <pragmas/graphics_pragmas.h>
  21. #include <clib/gadtools_protos.h>
  22. #include <pragmas/gadtools_pragmas.h>
  23. #include <graphics/gfxbase.h>
  24. #include <utility/tagitem.h>
  25. #include <utility/hooks.h>
  26. #include <intuition/sghooks.h>
  27. #include <intuition/intuition.h>
  28. #include <clib/alib_protos.h>
  29.  
  30. #include <string.h>
  31.  
  32. LONG __saveds RequestString(void);
  33. ULONG __saveds __asm HookFunc(register __a0 struct Hook *TheHook,
  34.                               register __a2 struct SGWork *Obj,
  35.                               register __a1 APTR Mess);
  36.  
  37.  
  38. #define  TEMPLATE "STRING,TEXT/K,TITLE/K,NOGADS/S,WIDTH/N,SAFE/S,PERSIST/S,ENCRYPT/S,COMPARE/K,PUBSCREEN/K"
  39.  
  40. #define  NArgs 10          /* Number of arguments */
  41.  
  42. #define  STRING      0
  43. #define  TEXT        1
  44. #define  TITLE       2
  45. #define  NOGADS      3
  46. #define  WIDTH       4
  47. #define  SAFE        5
  48. #define  PERSIST     6
  49. #define  ENCRYPT     7
  50. #define  COMPARE     8
  51. #define  PUBSCREEN   9
  52.  
  53. #define  MINWIDTH    8     /* Minimum width of gadget in characters */
  54.  
  55. LONG __saveds RequestString(void)
  56. {
  57. struct DosLibrary       *DOSBase=NULL;
  58. struct Library          *GadToolsBase=NULL;
  59. struct IntuitionBase    *IntuitionBase=NULL;
  60. struct GfxBase          *GfxBase=NULL;
  61.  
  62. LONG                    ArgList[NArgs];
  63. ULONG                   MsgClass=0;
  64. APTR                    VisInfo=NULL;
  65. char                    CBuffer[12],UName[48];
  66. struct TextExtent       TExtent;
  67. struct Hook             SGHook={0,0,0};
  68. struct RDArgs           *Args=NULL;
  69. struct ExtIntuiMessage  *EIMess=NULL;
  70. struct Gadget           *Gad=NULL,*GList=NULL;
  71. struct Window           *Win=NULL;
  72. struct Screen           *Scr=NULL;
  73. char                    *ReturnText=NULL;
  74.  
  75. int                     WWidth=0,WHeight=0;
  76. int                     GWidth=32,GHeight=1;
  77. long                    TXPos=0,TYPos=0;
  78.  
  79. LONG                    Ret=20;
  80.  
  81. const char *v="$VER: RequestString 39.4 (18.05.97)"; /* Bump this to 4X.1? */
  82.  
  83. struct TagItem WindowTags[]={
  84.    {WA_PubScreen,0},
  85.    {WA_Gadgets,0},
  86.    {WA_Left,0},
  87.    {WA_Top,0},
  88.    {WA_Width,0},
  89.    {WA_Height,0},
  90.    {WA_DragBar,FALSE},
  91.    {WA_DepthGadget,FALSE},
  92.    {WA_CloseGadget,FALSE},
  93.    {WA_Title,NULL},
  94.    {WA_IDCMP,IDCMP_GADGETUP|IDCMP_INACTIVEWINDOW|IDCMP_ACTIVEWINDOW|IDCMP_REFRESHWINDOW|IDCMP_CLOSEWINDOW},
  95.    {WA_SizeGadget,FALSE},
  96.    {WA_Activate,TRUE}
  97. };
  98.  
  99. struct NewGadget  StringGad={10,5,80,15,NULL,NULL,0,0L,NULL,NULL};
  100.  
  101. if((DOSBase=(struct DosLibrary *)OpenLibrary("dos.library",39L))!=NULL){
  102. if((GfxBase=(struct GfxBase *)OpenLibrary("graphics.library",39L))!=NULL){
  103. if((IntuitionBase=(struct IntuitionBase *)OpenLibrary("intuition.library",39L))!=NULL){
  104. if((GadToolsBase=OpenLibrary("gadtools.library",39L))!=NULL){
  105.  
  106. memset(ArgList,0,NArgs*sizeof(LONG)); /* Clear the ArgList array */
  107.  
  108. Args=ReadArgs(TEMPLATE,ArgList,NULL);  /* How do we check for failure? */
  109. if((Scr=LockPubScreen((UBYTE *)ArgList[PUBSCREEN]))!=NULL){
  110. if((VisInfo=GetVisualInfo(Scr,NULL))!=NULL){
  111. if((Gad=CreateContext(&GList))!=NULL){
  112.  
  113. if(ArgList[WIDTH]!=0)GWidth = *((LONG *)ArgList[WIDTH]);
  114. if(GWidth<8)GWidth=8;
  115.  
  116. GHeight=GHeight*Scr->RastPort.TxHeight+6;
  117. WHeight=GHeight+8;
  118.  
  119. do{
  120.    GWidth=GWidth*Scr->RastPort.TxWidth+4;
  121.    WWidth=GWidth+20;
  122.    if(WWidth>Scr->Width)
  123.       GWidth=(Scr->Width-20)/(Scr->RastPort.TxWidth)-1;
  124. }while(WWidth>Scr->Width);
  125.  
  126. /* Forbid()/Permit() around this following poking in GfxBase? */
  127.  
  128. FontExtent(GfxBase->DefaultFont,&TExtent);
  129.  
  130. if(ArgList[TEXT]!=0){
  131.    WHeight+=(TExtent.te_Height);
  132.    if((TExtent.te_Width*strlen((char *)ArgList[TEXT])+20)>WWidth)
  133.       WWidth=(TExtent.te_Width*strlen((char *)ArgList[TEXT])+20);
  134. }
  135.  
  136. /* If the window has a title, it will also have a dragbar, closegadget
  137.  * and a depthgadget.
  138.  */
  139. if(ArgList[TITLE]!=0){
  140.    WindowTags[6].ti_Data=TRUE;
  141.    if(ArgList[NOGADS]==0){
  142.       WindowTags[7].ti_Data=TRUE;
  143.       WindowTags[8].ti_Data=TRUE;
  144.    }
  145.    WindowTags[9].ti_Data=(ULONG)ArgList[TITLE];
  146.    WHeight+=Scr->RastPort.TxHeight; /* Should be Win->BorderTop, see also note below. */
  147. }
  148.  
  149. StringGad.ng_VisualInfo=VisInfo;
  150. StringGad.ng_Width=GWidth;
  151. StringGad.ng_Height=GHeight;
  152. StringGad.ng_TopEdge=WHeight-(GHeight+4); /* The '4' should be replaces by Win->BorderTop but how? The window is not yet opened. */
  153. StringGad.ng_LeftEdge=(WWidth-GWidth)>>1;
  154.  
  155. /* Initialize the Hook if we are using a safe stringgadget.
  156.  * SGHook.d_Data points to storage space for the string which
  157.  * will be returned. Memory sould be cleared.
  158.  */
  159.  
  160. if(ArgList[SAFE]!=0){
  161.    SGHook.h_Entry=(unsigned long (*)())HookFunc;
  162. /* SGHook.h_SubEntry=NULL; */
  163.    SGHook.h_Data=AllocVec(98,MEMF_ANY|MEMF_CLEAR); /* Should be made dynamic if possible */
  164.    if(ArgList[STRING]!=0){
  165.       int   i = -1;
  166.       strcpy((char *)SGHook.h_Data,(char *)ArgList[STRING]);
  167.       while(((char *)ArgList[STRING])[++i]!=0)((char *)ArgList[STRING])[i]='*';
  168.    }
  169. }
  170.  
  171. /* Here goes nothing... */
  172.  
  173. if((Gad=CreateGadget(STRING_KIND,Gad,&StringGad,GTST_EditHook,(ArgList[SAFE]==0)?NULL:&SGHook,GTST_String,ArgList[STRING],TAG_END))!=NULL){
  174.  
  175. /* Screen Gadget */
  176. WindowTags[0].ti_Data=(ULONG)Scr;
  177. WindowTags[1].ti_Data=(ULONG)GList;
  178. /* Width & Height */
  179. WindowTags[4].ti_Data=(ULONG)WWidth;
  180. WindowTags[5].ti_Data=(ULONG)WHeight;
  181. /* X & Y Pos */
  182. WindowTags[2].ti_Data=(ULONG)(Scr->Width-WWidth)>>1;
  183. WindowTags[3].ti_Data=(ULONG)(Scr->Height-WHeight)>>1;
  184.  
  185. if((Win=OpenWindowTagList(NULL,WindowTags))!=NULL){
  186.  
  187. /* Is there some (un)informative text in the window? */
  188.  
  189. if(ArgList[TEXT]!=0){
  190.    SetAPen(Win->RPort,1);  /* Colour should rather be selected with thougt to the background of the window, fix this. */
  191.    TXPos=(WWidth-TextLength(Win->RPort,(char *)ArgList[TEXT],(unsigned long)strlen((char *)ArgList[TEXT])))>>1;
  192.    TYPos=GfxBase->DefaultFont->tf_Baseline+Win->BorderTop+1;
  193.    Move(Win->RPort,TXPos,TYPos);
  194.    Text(Win->RPort,(char *)ArgList[TEXT],(unsigned long)strlen((char *)ArgList[TEXT]));
  195. }
  196.  
  197. do{
  198.  
  199. WaitPort(Win->UserPort);
  200.  
  201. EIMess=(struct ExtIntuiMessage *)GT_GetIMsg(Win->UserPort);
  202.  
  203. MsgClass=EIMess->eim_IntuiMessage.Class;
  204.  
  205. GT_ReplyIMsg((struct IntuiMessage *)EIMess);
  206.  
  207. switch(MsgClass) {
  208.  
  209. case  IDCMP_ACTIVEWINDOW   :
  210.    ActivateGadget(Gad,Win,NULL);
  211. break;
  212.  
  213. case  IDCMP_INACTIVEWINDOW :
  214.    if(ArgList[PERSIST]){
  215.    ScreenToFront(Win->WScreen);
  216.    WindowToFront(Win);
  217.    ActivateWindow(Win);
  218.    }
  219. break;
  220.  
  221. case  IDCMP_REFRESHWINDOW  :
  222.    GT_BeginRefresh(Win);
  223.    if(ArgList[TEXT]!=0){
  224.       Move(Win->RPort,TXPos,TYPos);
  225.       Text(Win->RPort,(char *)ArgList[TEXT],(unsigned long)strlen((char *)ArgList[TEXT]));
  226.    }
  227.    GT_EndRefresh(Win,TRUE);
  228. break;
  229.  
  230.  
  231. }
  232.  
  233. }while((MsgClass!=IDCMP_GADGETUP) && (MsgClass!=IDCMP_CLOSEWINDOW));
  234.  
  235. GT_GetGadgetAttrs(Gad,Win,NULL,GTST_String,&ReturnText,TAG_END);
  236.  
  237. if(ArgList[SAFE]!=0)ReturnText=(char *)SGHook.h_Data;
  238.  
  239. /* Try to find out who the user is if we are to encrypt the output.   */
  240. /* I really don't know how to acquire the username, but this might    */
  241. /* be a good guess of how to do it.                                   */
  242.  
  243. if(ArgList[ENCRYPT]!=0){
  244.    if(GetVar("USER",UName,47,0L)==-1)
  245.       if(GetVar("USERNAME",UName,47,0L)==-1)
  246.          if(GetVar("LOGIN",UName,47,0L)==-1)
  247.                UName[0]=0;
  248.    ACrypt(CBuffer,ReturnText,UName);
  249.    ReturnText=CBuffer;
  250. }
  251.  
  252. Printf("\"%s\"\n",ReturnText);
  253.  
  254. /* Here follows the COMPARE parameter. If the input string is not equal
  255.  * to the argument of COMPARE we return WARN.
  256.  */
  257.  
  258. if(ArgList[COMPARE]!=0)
  259.    Ret=(strcmp(ReturnText,(char *)ArgList[COMPARE]))?RETURN_WARN:0;
  260. else
  261.    Ret=0;
  262.  
  263. }}}}  /* if:s */
  264.  
  265. /* LockPubScreen failure only warrants a 10 if user defined a screen */
  266. } else if(ArgList[PUBSCREEN]!=0)Ret=10;
  267.  
  268. /* Clean up. */
  269.  
  270. if(SGHook.h_Data!=NULL)FreeVec(SGHook.h_Data);
  271. if(Args)FreeArgs(Args);
  272. if(Win)CloseWindow(Win);
  273. if(GList)FreeGadgets(GList);
  274. if(VisInfo)FreeVisualInfo(VisInfo);
  275. if(Scr)UnlockPubScreen(NULL,Scr);
  276.  
  277. CloseLibrary(GadToolsBase);
  278. }
  279. CloseLibrary((struct Library *)IntuitionBase);
  280. }
  281. CloseLibrary((struct Library *)GfxBase);
  282. }
  283. CloseLibrary((struct Library *)DOSBase);
  284. }
  285.  
  286. return(Ret);
  287.  
  288. }
  289.  
  290.  
  291. /* EditHook function for safe stringgadgets */
  292.  
  293.  
  294. ULONG __saveds __asm HookFunc(register __a0 struct Hook *TheHook,
  295.                               register __a2 struct SGWork *Obj,
  296.                               register __a1 ULONG *Mess)
  297. {
  298. int   i0,i1;
  299. char  * const Tmp=(char *)(TheHook->h_Data);
  300.  
  301. if(Mess[0]==SGH_KEY)
  302. {
  303.    Obj->Actions|=SGA_USE;
  304.  
  305.    switch(Obj->EditOp)
  306.    {
  307.    case  EO_DELBACKWARD :
  308.       i0=Obj->StringInfo->BufferPos;
  309.       i1=(Obj->StringInfo->NumChars)-(Obj->NumChars);
  310.       strcpy(&Tmp[i0-i1],&Tmp[i0]);
  311.    break;
  312.  
  313.    case  EO_DELFORWARD :
  314.       i0=Obj->StringInfo->BufferPos;
  315.       i1=(Obj->StringInfo->NumChars)-(Obj->NumChars);
  316.       strcpy(&Tmp[i0],&Tmp[i0+i1]);
  317.    break;
  318.  
  319.    case  EO_ENTER :
  320.       /* Exit handling. */
  321.    break;
  322.  
  323.    case  EO_RESET :
  324.       Tmp[0]=0;
  325.    break;
  326.  
  327.    case  EO_INSERTCHAR :
  328.       if(strlen(Tmp)>96)Obj->Actions&=~SGA_USE;
  329.       i0=Obj->StringInfo->BufferPos;
  330.       Obj->WorkBuffer[i0]='*';
  331.       i1=strlen(Tmp)+1;
  332.       while(i1--!=i0)Tmp[i1+1]=Tmp[i1];
  333.       Tmp[i0]=Obj->Code;
  334.    break;
  335.  
  336.    case  EO_CLEAR :
  337.       Tmp[0]=0;
  338.    break;
  339.  
  340.    case  EO_BIGCHANGE : /* Not Allowed */
  341.    case  EO_UNDO :
  342.    case  EO_SPECIAL : 
  343.       Obj->Actions&=~SGA_USE;
  344.    break;
  345.    }
  346.  
  347.    return(~0);
  348. } else {
  349.    Obj->Actions&=~SGA_USE;
  350.  
  351.    return(0);
  352. }
  353.  
  354. }
  355.